// FunctionTemplate

#include <iostream>

// 函数模板使用了泛型编程的思想
// 通过将类型传递给参数,使编译器生成这种类型的函数
// 如果要使用 函数模板 , 有两个关键字是必须的: template 和 typename(除非使用class关键字代替typename)

// 下面是一个函数模板的声明
// template <typename AnyType>
// void FunctionName(AnyType a,AnyType b){
//     AnyType temp;
//     temp = a;
//     a = b;
//     b = temp;
// }

// 在C++98添加typename关键字之前,C++使用class关键字来创建模板,就像下面这样
// template <class AnyType>
// void FunctionTemplate(AnyType a, AnyType b){
//     AnyType temp;
//     temp = a;
//     a = b;
//     b = temp;
// }

// 在这两种上下文中,typename和class是等价的
template <typename T>
void Swap(T &a, T &b);

template <typename T>
void Swap(T a[], T b[], int n);

    int main()
{
    using namespace std;
    int i = 10;
    int j = 20;

    cout << "i, j = " << i << ", " << j << ".\n";
    cout << "Using Compiler generated int swaper" << endl;
    Swap(i, j);
    cout << "Now i, j = " << i << ", " << j << ".\n";

    double x = 24.5;
    double y = 81.7;

    cout << "x, y = " << x << ", " << y << ".\n";
    cout << "Using Compiler generated double swaper" << endl;
    Swap(x, y);
    cout << "Now i, j = " << i << ", " << j << ".\n";

    return 0;
}
// 使用模板函数并不会减少最终可执行程序的大小，因为在调用模板函数时，编译器都根据调用时的参数类型进行了相应实例化
// 注意函数模版不能缩短可执行程序,最终仍将有两个独立的函数定义，就像以手工方式定义了这些函数一样，
// 最终的代码不包含任何模板，而只包含了为主程序生成的实际函数。使用模板的好处是它是生成多个函数定义更简单，更可靠。
template <typename T>
void Swap(T &a, T &b)
{
    T temp;
    temp = a;
    a = b;
    b = temp;
}

// 函数模板可以重载
template <typename T>
void Swap(T a[], T b[], int n)      // 这里最后一个类型是int类型,所以说不是所有的模板函数都需要使用模板类型
{
    for (int i = 0; i < n; i++)
    {
        T temp;
        temp = a;
        a = b;
        b = temp;
    }
}

// 函数模板的缺陷
// 见 29FunctionalTemplateDefective.cpp